﻿using System;

namespace CalculatorApplication
{
    class C
    {
        //1. in型参数
        public void Sum(int a, int b)
        {
            a += b;
        }

        //2. ref型参数
        public void Sum(ref int a, int b)
        {
            a += b;
        }

        //3. out型参数
        public void Sum1(out int a, int b)
        {
            a = b + 2;
        }

        public static void Main(string[] args)
        {
            C c = new C();
            int a = 1, b = 2;
            c.Sum(a, b);
            Console.WriteLine("a:{0}", a);
            a = 1; b = 2;
            c.Sum(ref a, b);
            Console.WriteLine("ref a:{0}", a);
            a = 1; b = 2;
            c.Sum1(out a, b);
            Console.WriteLine("out a:{0}", a);
            Console.ReadKey();
        }
    }
}
/*
 
 
方法中参数的类型有三种
in型参数

int 型参数通过值传递的方式将数值传入方法中，即我们在Java中常见的方法。
ref型参数

该种类型的参数传递变量地址给方法（引用传递），传递前变量必须初始化。

该类型与out型的区别在与：

 1）.ref 型传递变量前，变量必须初始化，否则编译器会报错, 而 out 型则不需要初始化
 2）.ref 型传递变量，数值可以传入方法中，而 out 型无法将数据传入方法中。换而言之，ref 型有进有出，out 型只出不进。
out 型参数

与 ref 型类似，仅用于传回结果。

注意：

1). out型数据在方法中必须要赋值，否则编译器会报错。

eg:如下图若将代码中的sum1方法的方法体

改为 a+=b; 则编译器会报错。原因：out 型只出不进，在没给 a 赋值前是不能使用的

改为 b+=b+2; 编译器也会报错。原因：out 型数据在方法中必须要赋值。

2). 重载方法时若两个方法的区别仅限于一个参数类型为ref 另一个方法中为out，编译器会报错

eg：若将下面的代码中将方法名 vsum1 改为 sum（或者将方法名 sum 改为 sum1），编译器会报错。

Error 1 Cannot define overloaded method ‘sum’ because it differs from another method only on ref and out 
原因：参数类型区别仅限于 为 ref 与为 out 时，若重载对编译器而言两者的元数据表示完全相同。
 



从代码也可以看出，int 型参数为值传递，所以当将变量 a 传入方法时，变量 a 的值并不会发生变化。而 ref 型参数，由于是引用传递，将变量的值和地址都传入方法中故变量值改变。out 型无法将变量的值传入。但可以将变量的地址传入并为该地址上的变量赋值。
 */